package com.hmy.uaa.common.security;

import org.springframework.security.authentication.AccountStatusUserDetailsChecker;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;

/**
 * 提供刷新token时采用自定义UserDetailsService
 *
 * @author xiongwei
 */
public class UserIdAuthenticationProvider implements AuthenticationProvider {

    private UserIdDetailsService userIdDetailsService;

    private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        PreAuthenticatedAuthenticationToken preAuthenticatedAuthenticationToken = (PreAuthenticatedAuthenticationToken) authentication;
        String userId = ((User) ((UsernamePasswordAuthenticationToken) preAuthenticatedAuthenticationToken.getPrincipal()).getPrincipal()).getUsername();
        UserDetails userDetails = userIdDetailsService.loadUserByUsername(String.valueOf(userId));
        userDetailsChecker.check(userDetails);
        PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken(
                userDetails, authentication.getCredentials(), userDetails.getAuthorities());
        result.setDetails(authentication.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return (PreAuthenticatedAuthenticationToken.class
                .isAssignableFrom(authentication));
    }

    public UserIdAuthenticationProvider(UserIdDetailsService userIdDetailsService) {
        this.userIdDetailsService = userIdDetailsService;
    }
}
